﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CygwinPackageManager.Common;
using System.IO;

namespace CygwinPackageManager
{
	public partial class InstallationInfoBox : Form
	{
		#region LifeCycle
		public InstallationInfoBox()
		{
			InitializeComponent();
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			this.ShowProgress("Please wait while loading the mirror list...");
			bwGetMirrors.RunWorkerAsync();
		}
		#endregion

		#region Event Handlers
		private void btnChangeRoot_Click(object sender, EventArgs e)
		{
			switch (folderBrowserDialog1.ShowDialog())
			{
				case DialogResult.OK:
					tbRoot.Text = folderBrowserDialog1.SelectedPath;
					break;
			}
		}

		private void btnAccept_Click(object sender, EventArgs e)
		{
			string rootDirectory = tbRoot.Text;

			#region Validation
			List<string> validationErrors = new List<string>();
			if (!Directory.Exists(rootDirectory))
				validationErrors.Add("The selected installation folder does not exist.");

			if (validationErrors.Count > 0)
			{
				MessageBox.Show(validationErrors.ToFormattedList(), "Validation");
				return;
			}
			#endregion

			string mirrorUri = (lbMirrors.SelectedItem as Mirror).Uri;

			bool installationChanged = false;
			try
			{
				installationChanged = InstallationManager.SaveInstallationInfo(rootDirectory, rootDirectory, mirrorUri, cbAllUsers.Checked);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
				return;
			}

			if (installationChanged)
			{
				this.ShowProgress("Please wait while updating installation information...");
				bwInstallationInitializer.RunWorkerAsync();
			}
		}

		#region Background Workers
		private void bwGetMirrors_DoWork(object sender, DoWorkEventArgs e)
		{
			try
			{
				e.Result = (new MirrorDALC()).GetMirrors();
			}
			catch (Exception ex)
			{
				e.Result = ex.Message;
			}
		}

		private void bwGetMirrors_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			if (e.Result is IEnumerable<Mirror>)
			{
				IEnumerable<Mirror> mirrors = from mirror in e.Result as IEnumerable<Mirror>
											  orderby mirror.Name
											  select mirror;
				lbMirrors.DataSource = mirrors.ToList();

				InstallationInfo installation = InstallationManager.GetInstallationInfo();

				if (installation.IsNew)
				{
					btnChangeRoot.Text = "Select";
				}
				else
				{
					btnChangeRoot.Text = "Change";
					tbRoot.Text = installation.RootDirectory;
					cbAllUsers.Checked = installation.AllUsers.Value;
					lbMirrors.SelectedItem = mirrors.First(m => m.Uri == installation.LastMirrorUri.OriginalString);
				}

				this.HideProgress();
			}
			else
			{
				string error = e.Result as string;
				MessageBox.Show(error);
				Close();
			}
		}

		private void bwInstallationInitializer_DoWork(object sender, DoWorkEventArgs e)
		{
			try
			{
				InstallationManager.PrepareInstallation();
			}
			catch (Exception ex)
			{
				e.Result = ex.Message;
			}
		}

		private void bwInstallationInitializer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			string error = e.Result as string;
			if (string.IsNullOrEmpty(error))
			{
				DialogResult = DialogResult.OK;
				Close();
			}
			else
			{
				MessageBox.Show(error);
				this.HideProgress();
			}
		}
		#endregion

		#endregion
	}
}
